package com.liuym.student.interceptor;

import com.liuym.common.utils.FastJsonUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

/**
 * Controller方法拦截器，记录调用日志
 *
 * @author Liuym
 * @date 2019/01/21 11:37
 */
@Aspect
@Component
public class ControllerInterceptor {
    private static final Logger log = LoggerFactory.getLogger(ControllerInterceptor.class);

    /**
     * 定义拦截规则：拦截controller包下面的所有类中，有@RequestMapping注解的方法
     *
     * @return void
     */
    @Pointcut("execution(* com.liuym.student.controller..*(..))")
    public void methodPointcut() {
    }

    /**
     * 拦截器具体实现
     *
     * @param pjp
     * @return java.lang.Object
     */
    @Around("methodPointcut()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        MethodSignature signature = (MethodSignature) pjp.getSignature();//被拦截的方法签名
        String className = pjp.getTarget().getClass().getSimpleName();//类名
        String methodName = signature.getName();//方法名
        String apiName = className + "." + methodName;//接口名

        String[] paramNames = signature.getParameterNames();//参数名称
        Object[] paramValues = pjp.getArgs();//参数值
        StringBuilder paramSb = new StringBuilder();
        for (int i = 0; i < paramNames.length; i++) {
            if (i > 0) {
                paramSb.append(", ");
            }
            paramSb.append(paramNames[i]);
            paramSb.append("=");
            paramSb.append(paramValues[i]);
        }
        log.info("【调用接口】开始：apiName={}, {}", apiName, paramSb);

        Object result = null;
        long beginTime = System.currentTimeMillis();
        try {
            result = pjp.proceed();//执行被拦截的方法
        } finally {
            String response = null;
            if (result == null) {
                response = null;
            } else if (result instanceof String) {
                response = (String) result;
            } else {
                response = FastJsonUtil.obj2jsonOfFilter(result);
            }
            long time = System.currentTimeMillis() - beginTime;//执行时间
            log.info("【调用接口】结束：apiName={}, time={}, response={}", apiName, time, response);
        }
        return result;
    }

}